package langnstats.project.languagemodel.ngram;

import java.util.HashMap;
import java.util.Map;

import langnstats.project.lib.WordType; 
import langnstats.project.lib.crossvalidation.TrainTokens;
import langnstats.project.tools.CountMap;

public class NgramAnalysis {
	private int n;
	private NgramAnalysis(int n){
		this.n = n;
		counters = new NgramCounter[n];
		for(int i=0; i<n; i++){
			counters[i] = new NgramCounter<WordType>();
		}
	}
	
	private NgramCounter<WordType>[] counters;
	
	private void analyze(WordType[] trainTokens) {
		History<WordType> trainHistory = new History<WordType>();
		for(WordType wt : trainTokens){
			
			trainHistory.trim(n-1);
			for(int i=0; i<n; i++){
				History<WordType> tmpHistory = new History<WordType>(trainHistory);
				tmpHistory.trim(i);
				NgramCounter<WordType> ngramCounter = counters[i];
				CountMap<WordType> tmpMap = ngramCounter.get(tmpHistory);
				tmpMap.increCount(wt);
			}
		
			trainHistory.add(wt);
		}
	}
	
	public int getN(){ return n; }
	public NgramCounter<WordType> getNgramCounter(int n){
		if(this.n<n){
			throw new IllegalArgumentException("NgramAnalysis is done until "+this.n+"-gram. "+n+"-gram analysis is not done!");
		}
		return this.counters[n-1];
	}
	
	
	// STATIC stuffs
	private static Map<Integer, NgramAnalysis> analysisMap = new HashMap<Integer,NgramAnalysis>();
	
	public static NgramAnalysis getAnalysis(TrainTokens trainTokens, int n){
		NgramAnalysis analysis = analysisMap.get(trainTokens);
		if(analysis!=null){ return analysis; }
		
		analysis = new NgramAnalysis(n);
		analysisMap.put(trainTokens.getID(), analysis);
	
		analysis.analyze(trainTokens.getTokenArray());
		return analysis;
	}
}
